package pl.edu.agh.anomalyids.lerad.util;

import java.util.HashSet;

import pl.edu.agh.anomalyids.lerad.aspect.AbstractAspect;
import pl.edu.agh.anomalyids.lerad.aspect.enums.AspectType;
import pl.edu.agh.anomalyids.network.Packet;
import pl.edu.agh.anomalyids.network.Packet.Protocol;
import pl.edu.agh.anomalyids.network.header.impl.HTTPHeader;
import pl.edu.agh.anomalyids.network.header.impl.ICMPHeader;
import pl.edu.agh.anomalyids.network.header.impl.IPv4Header;
import pl.edu.agh.anomalyids.network.header.impl.TCPHeader;
import pl.edu.agh.anomalyids.network.header.impl.UDPHeader;

public class ImplicationValueAdder {

	@SuppressWarnings("unchecked")
	public static void tryAdd(Packet packet, AbstractAspect<?> aspect) {
		AspectType type = aspect.getType();
		switch (type) {
			case DESTIP:
				if (hasProtocol(packet, Protocol.IPv4)) {
					((HashSet<String>)aspect.getValues()).add(((IPv4Header) packet.getProtocols().get(Protocol.IPv4)).getDestAddress());
				}
				break;
			case DESTPORT:
				if (!hasProtocol(packet, Protocol.TCP)) {
					if (hasProtocol(packet, Protocol.UDP)) {
						((HashSet<Integer>)aspect.getValues()).add(((UDPHeader) packet.getProtocols().get(Protocol.UDP)).getDestPort());
					}
				} else {
					((HashSet<Integer>)aspect.getValues()).add(((TCPHeader) packet.getProtocols().get(Protocol.TCP)).getDestPort());
				}
				
				break;
			case HTTPMETHOD:
				if (hasProtocol(packet, Protocol.HTTP)) {
					((HashSet<String>)aspect.getValues()).add(((HTTPHeader) packet.getProtocols().get(Protocol.HTTP)).getRequestMethod());
				}
			case ICMPCODE:
				if (hasProtocol(packet, Protocol.ICMP)) {
					((HashSet<Integer>)aspect.getValues()).add(((ICMPHeader) packet.getProtocols().get(Protocol.ICMP)).getCode());
				}
				break;
			case ICMPTYPE:
				if (hasProtocol(packet, Protocol.ICMP)) {
					((HashSet<Integer>)aspect.getValues()).add(((ICMPHeader) packet.getProtocols().get(Protocol.ICMP)).getType());
				}
				break;
			case SRCIP:
				if (hasProtocol(packet, Protocol.IPv4)) {
					((HashSet<String>)aspect.getValues()).add(((IPv4Header) packet.getProtocols().get(Protocol.IPv4)).getSrcAddress());
				}
				break;
			case SRCPORT:
				if (!hasProtocol(packet, Protocol.TCP)) {
					if (hasProtocol(packet, Protocol.UDP)) {
						((HashSet<Integer>)aspect.getValues()).add(((UDPHeader) packet.getProtocols().get(Protocol.UDP)).getSrcPort());
					}
				} else {
					((HashSet<Integer>)aspect.getValues()).add(((TCPHeader) packet.getProtocols().get(Protocol.TCP)).getSrcPort());
				}
				
				break;
			case TCPFLAG:
				if (hasProtocol(packet, Protocol.TCP)) {
					((HashSet<Integer>)aspect.getValues()).add(((TCPHeader) packet.getProtocols().get(Protocol.TCP)).getFlags());
				}
				break;
			case TTL:
				if (hasProtocol(packet, Protocol.IPv4)) {
					((HashSet<Integer>)aspect.getValues()).add(((IPv4Header) packet.getProtocols().get(Protocol.IPv4)).getTTL());
				}
				break;
		}
	}
	
	private static boolean hasProtocol(Packet packet, Protocol protocol) {
		if (packet.getProtocols().get(protocol) != null) {
			return true;
		}
		
		return false;
	}
}
